//-------------------------------------------------------------------
//	Copyright (c) 2012-2014 Zhirnov Andrey
//	This file is part of the "UXGEN-ES" project.
//	See copyright notice in "Engine.h".
//-------------------------------------------------------------------

#pragma once

#include "Base/Platform/Device.h"

namespace Engine
{
namespace Base
{

	struct EDevice
	{
		enum type
		{
			AUTO	= 0,
			
			IPHONE3G,
			IPHONE3GS,
			IPHONE4,
			IPHONE4S,
			IPHONE5,

			IPAD2,
			IPAD3,
			IPAD4,

			IPAD_MINI,

			ANDROID_DEVICE,
			ANDROID_SE_XPIRIA_PRO,
			ANDROID_NEXUS_7_2013,
			ANDROID_SAMSUNG_GALAXY_Y,
			ANDROID_FLY_IQ238,

			DEF_QUAD_SCREEN,
		};
	};


	//
	// Device Emulator
	//

	struct DeviceEmulator
	{
	// config
	public:
		static uint		EmulatorPPI ()				{ return 104; }
		static float	EmulatorDisplayScale ()		{ return 2.0f; }
		static bool		PixelToPixel ()				{ return false; }


	// methods
	public:
		static void Create (Device &dev, EDevice::type type)
		{
			switch ( type )
			{
				case EDevice::IPHONE3G				:	iPhone3G( dev );				break;
				case EDevice::IPHONE3GS				:	iPhone3GS( dev );				break;
				case EDevice::IPHONE4				:	iPhone4( dev );					break;
				case EDevice::IPHONE4S				:	iPhone4S( dev );				break;
				case EDevice::IPHONE5				:	iPhone5( dev );					break;
				case EDevice::IPAD2					:	iPad2( dev );					break;
				case EDevice::IPAD3					:	iPad3( dev );					break;
				case EDevice::IPAD4					:	iPad4( dev );					break;
				case EDevice::IPAD_MINI				:	iPadMini( dev );				break;
				case EDevice::ANDROID_DEVICE		:	Android_Default( dev );			break;
				case EDevice::ANDROID_SE_XPIRIA_PRO	:	AndroidSeXpiriaPro( dev );		break;
				case EDevice::ANDROID_NEXUS_7_2013	:	AndroidNexus7_2013( dev );		break;
				case EDevice::ANDROID_SAMSUNG_GALAXY_Y:	AndroidSamsungGalaxyY( dev );	break;
				case EDevice::ANDROID_FLY_IQ238		:	AndroidFlyIQ238( dev );			break;
				case EDevice::DEF_QUAD_SCREEN		:	DefQuadScreen( dev );			break;
				default								:	WARNING( "Unknown device" );
			}

			dev._iso2Locale.Copy( uni_array<const char>( "en", 3 ) );
			dev._iso3Locale.Copy( uni_array<const char>( "eng", 4 ) );
		}


		static ScreenCoords::Pixels ToEmulatorScreen (const Display &display, const ScreenCoords::Pixels &devicePixels)
		{
			#if defined( MOBILE_EMULATOR )
				return  PixelToPixel() ? devicePixels :
						ScreenCoords::Pixels(
							Round<int>( EmulatorDisplayScale() * (float(EmulatorPPI()) /
										display.PPI()) * devicePixels.Get().To<vec2>() ) );
			#else
				return devicePixels;
			#endif
		}


		static ScreenCoords::Pixels ToDeviceScreen (const Display &display, const ScreenCoords::Pixels &emulatorPixels)
		{
			#if defined( MOBILE_EMULATOR )
				return	PixelToPixel() ? emulatorPixels :
						ScreenCoords::Pixels(
							Round<int>( emulatorPixels.Get().To<vec2>() / EmulatorDisplayScale() *
										(display.PPI() / float(EmulatorPPI())) ) );
			#else
				return emulatorPixels;
			#endif
		}


	private:
		static void iPhone3G (Device & dev)
		{
			Display & disp = dev._display;
			
			disp._res	 = ScreenCoords::Pixels(320, 480);
			disp._ppi	 = 163;
			disp._size	 = disp.CalcPhysicsSize();
			
			dev._numCPUs	= 1;
			dev._cpuFreq	= 412;
			dev._name		= "iPhone 3G";
			dev._os			= "iOS 4.2.1";
			dev._gpu		= "PowerVR MBX Lite 3D";
			dev._totalMem	= Bytes( 128 << 20 );
		}

		static void iPhone3GS (Device & dev)
		{
			Display & disp = dev._display;
			
			disp._res	 = ScreenCoords::Pixels(320, 480);
			disp._ppi	 = 163;
			disp._size	 = disp.CalcPhysicsSize();
			
			dev._numCPUs	= 1;
			dev._cpuFreq	= 600;
			dev._name		= "iPhone 3GS";
			dev._os			= "iOS 6.1.3";
			dev._gpu		= "PowerVR SGX535";
			dev._totalMem	= Bytes( 256 << 20 );
		}

		static void iPhone4 (Device & dev)
		{
			Display & disp = dev._display;
			
			disp._res	 = ScreenCoords::Pixels(640, 960);
			disp._ppi	 = 326;
			disp._size	 = disp.CalcPhysicsSize();
			
			dev._numCPUs	= 1;
			dev._cpuFreq	= 800;
			dev._name		= "iPhone 4";
			dev._os			= "iOS 6.1.3";
			dev._gpu		= "PowerVR SGX535";
			dev._totalMem	= Bytes( 512 << 20 );
		}

		static void iPhone4S (Device & dev)
		{
			Display & disp = dev._display;
			
			disp._res	 = ScreenCoords::Pixels(640, 960);
			disp._ppi	 = 326;
			disp._size	 = disp.CalcPhysicsSize();
			
			dev._numCPUs	= 1;
			dev._cpuFreq	= 800;
			dev._name		= "iPhone 4S";
			dev._os			= "iOS 6.1.3";
			dev._gpu		= "PowerVR SGX544 MP2";
			dev._totalMem	= Bytes( 512 << 20 );
		}

		static void iPhone5 (Device & dev)
		{
			Display & disp = dev._display;
			
			disp._res	 = ScreenCoords::Pixels(640, 1136);
			disp._ppi	 = 326;
			disp._size	 = disp.CalcPhysicsSize();
			
			dev._numCPUs	= 2;
			dev._cpuFreq	= 1200;
			dev._name		= "iPhone 5";
			dev._os			= "iOS 6.1.3";
			dev._gpu		= "PowerVR SGX543 MP3";
			dev._totalMem	= Bytes( 1024 << 20 );
		}

		static void iPad2 (Device & dev)
		{
			Display & disp = dev._display;
			
			disp._res	 = ScreenCoords::Pixels(1024, 768);
			disp._ppi	 = 163;
			disp._size	 = disp.CalcPhysicsSize();
			
			dev._numCPUs	= 2;
			dev._cpuFreq	= 1000;
			dev._name		= "iPad 2";
			dev._os			= "iOS 6.1.3";
			dev._gpu		= "PowerVR SGX543 MP2";
			dev._totalMem	= Bytes( 512 << 20 );
		}

		static void iPad3 (Device & dev)
		{
			Display & disp = dev._display;
			
			disp._res	 = ScreenCoords::Pixels(2048, 1536);
			disp._ppi	 = 264;
			disp._size	 = disp.CalcPhysicsSize();
			
			dev._numCPUs	= 2;
			dev._cpuFreq	= 1000;
			dev._name		= "iPad 3";
			dev._os			= "iOS 6.1.3";
			dev._gpu		= "PowerVR SGX543 MP4";
			dev._totalMem	= Bytes( 1024 << 20 );
		}

		static void iPad4 (Device & dev)
		{
			Display & disp = dev._display;
			
			disp._res	 = ScreenCoords::Pixels(2048, 1536);
			disp._ppi	 = 264;
			disp._size	 = disp.CalcPhysicsSize();
			
			dev._numCPUs	= 2;
			dev._cpuFreq	= 1400;
			dev._name		= "iPad 4";
			dev._os			= "iOS 6.1.3";
			dev._gpu		= "PowerVR SGX543 MP3";
			dev._totalMem	= Bytes( 1024 << 20 );
		}

		static void iPadMini (Device & dev)
		{
			Display & disp = dev._display;
			
			disp._res	 = ScreenCoords::Pixels(1024, 768);
			disp._ppi	 = 264;
			disp._size	 = disp.CalcPhysicsSize();
			
			dev._numCPUs	= 2;
			dev._cpuFreq	= 1000;
			dev._name		= "iPad Mini";
			dev._os			= "iOS 6.1.3";
			dev._gpu		= "PowerVR SGX543 MP2";
			dev._totalMem	= Bytes( 512 << 20 );
		}

		static void Android_Default (Device & dev)
		{
			Display & disp = dev._display;

			disp._res	 = ScreenCoords::Pixels(320, 480);
			disp._ppi	 = 144;
			disp._size	 = disp.CalcPhysicsSize();
			disp._orient = Display::ORIENT_0;

			dev._numCPUs	= 1;
			dev._cpuFreq	= 1000;
			dev._name		= "Android device";
			dev._os			= "Android 2.3.3";
			dev._totalMem	= Bytes( 512 << 20 );
		}

		static void AndroidSeXpiriaPro (Device & dev)
		{
			Display & disp = dev._display;

			disp._res	 = ScreenCoords::Pixels(480, 854);
			disp._ppi	 = 265;
			disp._size	 = disp.CalcPhysicsSize();
			disp._orient = Display::ORIENT_0;

			dev._numCPUs	= 1;
			dev._cpuFreq	= 1000;
			dev._name		= "SE Xpiria Pro";
			dev._os			= "Android 2.3.4";
			dev._gpu		= "Adreno 205";
			dev._totalMem	= Bytes( 300 << 20 );

			dev._hardwareKeyboard	= true;
			dev._keyboardOpen		= false;
		}

		static void AndroidNexus7_2013 (Device & dev)
		{
			Display & disp = dev._display;

			disp._res	 = ScreenCoords::Pixels(1200, 1920);
			disp._ppi	 = 320;
			disp._size	 = disp.CalcPhysicsSize();
			disp._orient = Display::ORIENT_0;

			dev._numCPUs	= 4;
			dev._cpuFreq	= 1500;
			dev._name		= "Nexus 7";
			dev._os			= "Android 4.3";
			dev._gpu		= "Adreno 320";
			dev._totalMem	= Bytes( 2000 << 20 );

			dev._hardwareKeyboard	= false;
			dev._keyboardOpen		= false;
		}
		
		static void AndroidSamsungGalaxyY (Device & dev)
		{
			Display & disp = dev._display;

			disp._res	 = ScreenCoords::Pixels(240, 320);
			disp._ppi	 = 133;
			disp._size	 = disp.CalcPhysicsSize();
			disp._orient = Display::ORIENT_0;

			dev._numCPUs	= 1;
			dev._cpuFreq	= 800;
			dev._name		= "Samsung Galaxy Y";
			dev._os			= "Android 2.3";
			dev._gpu		= "";
			dev._totalMem	= Bytes( 290 << 20 );

			dev._hardwareKeyboard	= false;
			dev._keyboardOpen		= false;
		}

		static void AndroidFlyIQ238 (Device & dev)
		{
			Display & disp = dev._display;

			disp._res	 = ScreenCoords::Pixels(320, 480);
			disp._ppi	 = 165;
			disp._size	 = disp.CalcPhysicsSize();
			disp._orient = Display::ORIENT_0;

			dev._numCPUs	= 1;
			dev._cpuFreq	= 1000;
			dev._name		= "Fly IQ238";
			dev._os			= "Android 2.3.5";
			dev._gpu		= "";
			dev._totalMem	= Bytes( 512 << 20 );

			dev._hardwareKeyboard	= false;
			dev._keyboardOpen		= false;
		}
			
		static void DefQuadScreen (Device & dev)
		{
			Display & disp = dev._display;

			disp._res	 = ScreenCoords::Pixels(480, 480);
			disp._ppi	 = 96;
			disp._size	 = disp.CalcPhysicsSize();
			disp._orient = Display::ORIENT_0;

			dev._numCPUs	= 1;
			dev._cpuFreq	= 1000;
			dev._name		= "default";
			dev._os			= "unknown";
			dev._gpu		= "";
			dev._totalMem	= Bytes( 512 << 20 );

			dev._hardwareKeyboard	= false;
			dev._keyboardOpen		= false;
		}
	};

	

	//
	// Device SetterGetter
	//

	inline void  Display::SetterGetter::SetResolution (Display &disp, const ScreenCoords::Pixels &res)
	{
		disp._res = DeviceEmulator::ToDeviceScreen( disp, res );
	}
	
	inline void  Display::SetterGetter::SetResolution (Device &dev, const ScreenCoords::Pixels &res)
	{
		SetResolution( dev._display, res );
	}

	inline ScreenCoords::Pixels Display::SetterGetter::GetResolution (const Display &disp)
	{
		return DeviceEmulator::ToEmulatorScreen( disp, disp._res );
	}
	
	inline void  Display::SetterGetter::SetOrientation (Display &disp, EOrientation orient)
	{
		disp._orient = orient;
	}


}	// Base
}	// Engine